﻿using System;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using SCG = System.Collections.Generic;

using Nemerle;
using Nemerle.Text;
using Nemerle.Compiler;
using Nemerle.Utility;
using PT = Nemerle.Compiler.Parsetree;
using TT = Nemerle.Compiler.Typedtree;

namespace Nemerle.OpenCL {

    [MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Class)]
    macro HandlePattern(tb : TypeBuilder, handle_type) {
        def release_func = regexp match(tb.Name) {
            | @"^(?<entity>\w+)Handle$" => <[ GASS.OpenCL.OpenCLDriver.$("clRelease" + entity : usesite) ]>
            | _ => Message.FatalError("Invalid CLhandle class name.")
        }
        tb.DisableImplicitConstructor();
        tb.Define(<[ decl:
            public this(entity_id : $handle_type) {
                base(IntPtr.Zero, true);
                this.entity_id = entity_id;
            }
        ]>);
        tb.Define(<[ decl:
            [Accessor] entity_id : $handle_type;
        ]>);
        tb.Define(<[ decl:
            public override IsInvalid : bool {
                get { entity_id.Value == IntPtr.Zero }
            }
        ]>);
        tb.Define(<[ decl:
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
            protected override ReleaseHandle() : bool {
                match($release_func(entity_id)) {
                    | GASS.OpenCL.CLError.Success => true
                    | _ => false
                }
            }
        ]>);
    }

}